package com.edoovo.loginservice.application.util;

import org.apache.commons.lang3.StringUtils;

import javax.validation.constraints.NotNull;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Objects;


public class TimeUtils {

    private static final Snowflake snowflake = new Snowflake(5, 5);
    private static final ZoneId CST = ZoneId.of("Asia/Shanghai");
    private static final ZoneId UTC = ZoneId.of("UTC");
    private static final String DDMMYYY = "dd/MM/yyyy";

    private TimeUtils() {
    }

    public static String dateNow() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(DDMMYYY);
        LocalDateTime now = LocalDateTime.now(CST);
        return df.format(now);
    }

    public static String dateNow(@NotNull LocalDateTime dateTime) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(DDMMYYY);
        df.withZone(CST);
        return df.format(dateTime);
    }

    public static String dueDate() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(DDMMYYY);
        LocalDateTime dueDateTime = LocalDateTime.now(CST).plusDays(14);
        return df.format(dueDateTime);
    }

    public static String invoiceNo() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String datetimeString = df.format(LocalDateTime.now());
        String randomId = snowflake.nextIdStr();
        return datetimeString + StringUtils.substring(randomId, randomId.length() - 4);
    }

    public static String helpCaseNo(){
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String datetimeStr = df.format(LocalDateTime.now());
        String randomId = snowflake.nextIdStr();
        return datetimeStr + StringUtils.substring(randomId, randomId.length() - 4);
    }

    public static String dateString(LocalDateTime dateTime) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return df.format(dateTime.toLocalDate());
    }

    public static Long toEpochMilli(LocalDateTime dateTime) {
        return dateTime.toInstant(ZoneOffset.UTC).toEpochMilli();
    }

    public static Long fromStart(LocalDateTime startDateTime, Long timestamp) {
        LocalDateTime endDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.of("UTC"));
        return Duration.between(startDateTime, endDateTime).toMillis();
    }

    public static Long fromStart(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        return Duration.between(startDateTime, endDateTime).toMillis();
    }

    public static LocalDateTime utcToCST(LocalDateTime utc){
        return utc.atZone(UTC).withZoneSameInstant(CST).toLocalDateTime();
    }

    public static LocalDateTime checkOutTime(LocalDateTime startDateTime, Long fromStart) {
        if (Objects.isNull(startDateTime))
            return null;
        return startDateTime.plus(fromStart, ChronoUnit.MILLIS);
    }


//    public static Integer studentAge(Date date) {
//        if (Objects.isNull(date))
//            return null;
//        LocalDate birth = LocalDate.ofInstant(date.toInstant(), ZoneId.systemDefault());
//        long duration = ChronoUnit.YEARS.between(birth, LocalDate.now());
//        return (int) duration;
//    }

    public static int daysOfCreated(LocalDateTime createDate) {
        if (Objects.isNull(createDate))
            return 0;
        LocalDate created = createDate.toLocalDate();
        long duration = ChronoUnit.DAYS.between(created, LocalDate.now());
        return (int) duration;
    }

}
